#include <stdio.h>
#include <unistd.h>

/*
 * 直接函数调用
 */

void func() ;

int main()
{
    int a;

    func();

    a = 0x66;
    func();

	while(1) {
		sleep(1);
	};
	return 0;
}

void func()
{
    int a;

    a++;
}

#if 0
/*
 * intel 
 */
0000000000001129 <main>:
    1129:	f3 0f 1e fa          	endbr64 
    112d:	55                   	push   %rbp				// rsp=rsp-8, (rsp)=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    112e:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    1131:	48 83 ec 10          	sub    $0x10,%rsp		// rsp=rsp-0x10
    1135:	b8 00 00 00 00       	mov    $0x0,%eax		// eax = 0
    113a:	e8 18 00 00 00       	callq  1157 <func>		// func()
    113f:	c7 45 fc 66 00 00 00 	movl   $0x66,-0x4(%rbp)	// a = rbp-0x4 = 0x66
    1146:	b8 00 00 00 00       	mov    $0x0,%eax		// eax = 0
    114b:	e8 07 00 00 00       	callq  1157 <func>		// func()
    1150:	b8 00 00 00 00       	mov    $0x0,%eax		// eax = 0
    1155:	c9                   	leaveq					// ===> mov %rbp,%rsp, pop %rbp
    1156:	c3                   	retq					// ===> pop %rip

0000000000001157 <func>:
    1157:	f3 0f 1e fa          	endbr64 
    115b:	55                   	push   %rbp				// rsp=rsp-8, (rsp)=rbp ===> subq $8,%rsp, movq %rbp,(%rsp)
    115c:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    115f:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)	// rpb-0x4 + 0x1
    1163:	90                   	nop
    1164:	5d                   	pop    %rbp				// rbp=(rsp), rsp+8 ===> movq (%rsp),%rbp, addq $8, %rsp
    1165:	c3                   	retq					// ===> pop %rip
    1166:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)	// 用于填补func之间的空白功能和main保持位元组对齐的功能
    116d:	00 00 00 

/*
 * arm
 */
000000000040051c <main>:
  40051c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!	// sp = sp-32, sp = x29, sp + 8 = x30,保护栈
  400520:	910003fd 	mov	x29, sp				// x29=fp=sp
  400524:	94000007 	bl	400540 <func>		// func()
  400528:	52800cc0 	mov	w0, #0x66           // w0 = #102
  40052c:	b9001fa0 	str	w0, [x29, #28]		// x29+28 = w0 = 0x66
  400530:	94000004 	bl	400540 <func>		// func()
  400534:	52800000 	mov	w0, #0x0            // #0
  400538:	a8c27bfd 	ldp	x29, x30, [sp], #32	// x29 = sp, x30 = sp + 8, sp = sp + 32,恢复栈
  40053c:	d65f03c0 	ret						// 子程序返回指令，返回地址默认保存在LR(X30)

0000000000400540 <func>:
  400540:	d10043ff 	sub	sp, sp, #0x10	// sp = sp - 0x10
  400544:	b9400fe0 	ldr	w0, [sp, #12]	// sp+12 = w0
  400548:	11000400 	add	w0, w0, #0x1	// w0 += 1
  40054c:	b9000fe0 	str	w0, [sp, #12]	// sp+12 = w0
  400550:	d503201f 	nop
  400554:	910043ff 	add	sp, sp, #0x10	// sp = sp + 0x10
  400558:	d65f03c0 	ret
  40055c:	00000000 	.inst	0x00000000 ; undefined


/*
 * nopw   %cs:0x0(%rax,%rax,1)
 */
	这是CPU管道的操作数转发优化，尽管这是一个空操作，但GCC也会尝试对此进行优化。

	有这行代码表示执行的CPU具有超标量体系结构，意味着具有管道，并且相继指令执行的不同阶段并行发生。

	"超标量是指在一个时钟周期内CPU可以执行一条以上的指令"

	就分支而言，即使無條件，流水線也要解決主要問题。

	例如，当 jmp 正在解碼時，下一條指令已預取到管道中.但是， jmp 更改下一條指令的位置.在這種情况下，
	需要清空並重新填充管道，這樣会丢失很多有value的CPU週期。

	看起来，如果在這種情况下管道填充為無操作，則该空迴圈將執行得更快，尽管它永远不会執行.
	實際上，它是對x86管道中一些不常见功能的優化。

	更早的dec alpha甚至可以隔离此類內容，並且空迴圈中必须包含很多no-op. x86只会更慢.這是因為它们必须与Intel 8086相容。

	这行代码用于填补func之间的空白功能和main保持位元组对齐的功能

	int foo(void)
    {
       return foo();
    }
    int main (void)
    {
       return foo();
    }

	0000000000400480 <foo>:
    foo():
    400480:       eb fe                   jmp    400480 <foo>
    400482:       66 66 66 66 66 2e 0f    data32 data32 data32 data32 nopw %cs:0x0(%rax,%rax,1)
    400489:       1f 84 00 00 00 00 00
    0000000000400490 <main>:
    main():
    400490:       eb fe                   jmp    400490 <main>

	x86體系結構具有大量不同大小的不同NOP指令，這些指令可用於將填充插入可執行段中，這樣，如果CPU最终在它们之上執行，
	它们將不起作用.然後，英特爾優化手册包含有關建議的NOP編碼的資訊，這些NOP編碼可以用作填充的不同长度。

	在這種特定情况下，它是完全不相關的，因為NOP將永远不会執行(甚至在無條件跳轉之後甚至会被解碼)，
	因此編譯器可以填充它想要的任何隨機垃圾。

	函式foo()是無终止的無限遞迴.如果不进行優化，則gcc会生成普通的子例程呼叫，
	其中至少包括堆棧返迴地址.由於堆棧受到限製，因此会产生_undefined_behaviour_的堆棧溢位。

	如果进行優化，則gcc会檢測到foo()完全不需要堆棧幀(没有引數或區域性變數).它還檢測到foo()立即返迴到呼叫方(也將是foo()).
	這被稱為尾鏈(tail-chaining)：將在函式末尾的函式呼叫(即顯式/隱式返迴)轉換為對该函式的跳轉，因此不需要堆棧。

	這仍然是不確定的行為，但是這次，没有观察到"壞"的情况。

	請記住：未定義包括致命行為以及預期行為(但這只是偶然).在不同的優化級別下表現不同的代碼應始终视為錯誤。 
	有一个例外：計時.這不受C語言標準(大多數其他語言都没有)的約束。

#endif
